//完成 测试正常
/*
 * Graph 根据org.sysmo.server.node.item.graphgroup提供的参数返回图表
 * Copyright (C) 2009  LiuHao
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.sysmo.server.graph;

import java.awt.image.*;
import java.io.OutputStream;
import java.awt.*;
import java.util.*;

/**
 * 图表类Stub。
 *
 * @author LiuHao
 */
public class Graph {
    private BufferedImage tempgraph;
    private Vector tempvec;
    private String str;

    /**
     * 画图函数，由org.sysmo.server.node.item.graphgroup包提供4个参数返回图形。
     * <br />
     *
     * 函数实现方式：变量GraphPoints是一个二维数组，他存储着多个监控项在一定时间内的
     * 点阵列（点以Point形式表示），首先按AxisPara参数所规定的数据画出坐标轴和参照线，
     * 由GraphPoints中的数据确定坐标轴的最大值和最小值和单位分划，确定若干个标志点
     * 然后按照DerivInteg参数的值将GraphPoints中的各个数组转化为对应的积分/导数/原值
     * 点阵存储在原vector中，最后按照GraphMode的要求将这些点阵画在拟定好的坐标轴上
     *
     * @param GraphPoints vector型的坐标集合
     * @param GraphMode 整型的图表显示模式(面图，线图等)参数 值为0时使用线图，值为
     * 1时使用面积图
     * @param AxisPara 各个数据的数据名稽核
     * @param DerivInteg vector型的求导或求积分参数列 0为不做操作，1为对点阵做求导
     * 操作，2为对点阵求积操作
     * @param OS 输出JPG所用的流参数
     *
     * @return tempgraph 返回一个指向已生成的.jpg格式图表
     */

    public BufferedImage drawGragh(Vector<Vector<Point>> GraphPoints, int GraphMode, OutputStream OS, Vector<String> AxisPara, Vector<Integer> DerivInteg){
        //计算并生成图形的过程
        //生成的图形暂时存在tempgraph中
        int width = 650, height = 200;
        int xLength = 550, yLength = 150;
        int maxY = 0;
        int i,j;
        Color color;
        int count = DerivInteg.size();
        int counti = GraphPoints.elementAt(0).size();
        tempvec = new Vector<Point>();

        Random r1=new Random();
        int re;
        int gr;
        int bl;



        jeruGraphics jg = new jeruGraphics();
        jg.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = jg.image.getGraphics();

        // 建立初始图形
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);
        g.setColor(Color.blue);
        g.drawLine(10,height-10,10,height-40-yLength);
        g.drawLine(10,height-40,10+xLength,height-40);

        if(GraphPoints.size()==0) {
            jg.createJpg(OS);
            return jg.getImage();
        }

        for(i=0;i<count;i++)
            if(GraphPoints.elementAt(i).size() == 0) {
                jg.createJpg(OS);
                return jg.getImage();
            }


        for(i=0;i<=10;i++){
            g.setColor(Color.LIGHT_GRAY);
            g.drawLine(10, height-40-i*yLength/10, 10 + xLength, height-40-i*yLength/10);
        }

        if(GraphPoints.elementAt(0).size() == 1){
            maxY = 0;
            for (i = 0; i < count; i++){

                   //遍历一个vector以求出Vector中Y值的最大值
                        if(maxY < GraphPoints.elementAt(i).elementAt(0).getValue())
                            maxY = GraphPoints.elementAt(i).elementAt(0).getValue();

            }
            for (i = 0; i < count; i++){
                re=r1.nextInt(200);
                gr=r1.nextInt(200);
                bl=r1.nextInt(200);
                color= new Color(re,gr,bl);
                g.setColor(new Color(re,gr,bl));
                g.fillOval(8, (int)((double)GraphPoints.elementAt(i).elementAt(0).getValue()*(double)yLength/(double)maxY), 4, 4);

                g.fillRect(15+xLength, height-38-yLength+i*10, 8, 8);
                g.drawString(AxisPara.elementAt(i), 25+xLength, height-30-yLength+i*10);
            }
            g.setColor(Color.black);
            g.drawString(GraphPoints.elementAt(0).elementAt(0).getTime().toString() ,13 ,height-5);

            tempgraph = jg.getImage();
            jg.createJpg(OS);

            return tempgraph;
        }

        
        for (i = 0; i < count; i++){
                if(DerivInteg.elementAt(i) == 1){
                    tempvec = derivative(GraphPoints.elementAt(i));
                    GraphPoints.removeElementAt(i);
                    GraphPoints.insertElementAt(tempvec, i);
                }
                else if(DerivInteg.elementAt(i) == 2){
                    tempvec = integral(GraphPoints.elementAt(i));
                    GraphPoints.removeElementAt(i);
                    GraphPoints.insertElementAt(tempvec, i);
                }
        }
        
        if (GraphMode==0){
            maxY = 0;
            for (i = 0; i < count; i++)
               //遍历一个vector以求出Vector中Y值的最大值
                for(j = 0; j < counti;j++)
                    if(maxY < GraphPoints.elementAt(i).elementAt(j).getValue())
                        maxY = GraphPoints.elementAt(i).elementAt(j).getValue();


            for (i = 0; i < count; i++)
            {
                //随机颜色
                re=r1.nextInt(200);
                gr=r1.nextInt(200);
                bl=r1.nextInt(200);
                color = new Color(re,gr,bl);
                g.setColor(new Color(re,gr,bl));

                jg.LineGraph(GraphPoints.elementAt(i),jg,maxY,color);

                g.drawLine(15+xLength, height-35-yLength+i*10, 23+xLength, height-35-yLength+i*10);
                g.drawString(AxisPara.elementAt(i), 25+xLength, height-30-yLength+i*10);
            }
        }
        
        else{
            int tempv = 0;
            Vector<Point> zerovec = new Vector<Point>();
            maxY = 0;

            for (j = 0; j < counti; j++){
                for(i = 0; i < count;i++){
                    tempv += GraphPoints.elementAt(i).elementAt(j).getValue();
                }
                if(maxY < tempv)
                    maxY = tempv;
                tempv = 0;
            }

            for(j = 0;j < counti;j++){
                zerovec.addElement(new Point(GraphPoints.elementAt(0).elementAt(j).getTime(),0));
            }


            for (i = 0; i< count ; i++){
                                //随机颜色
                re=r1.nextInt(200);
                gr=r1.nextInt(200);
                bl=r1.nextInt(200);
                color= new Color(re,gr,bl);
                g.setColor(new Color(re,gr,bl));

                jg.SqureGraph(GraphPoints.elementAt(i),zerovec, jg, maxY, color);

                for(j = 0;j < counti;j++){
                    tempv =zerovec.elementAt(j).getValue()+ GraphPoints.elementAt(i).elementAt(j).getValue();
                    zerovec.removeElementAt(j);
                    zerovec.insertElementAt(new Point(GraphPoints.elementAt(i).elementAt(j).getTime(), tempv),j);
                }

                g.fillRect(15+xLength, height-38-yLength+i*10, 8, 8);
//                g.drawLine(10+xLength, height-10-yLength+i*10, 15+xLength, height-10-yLength+i*10);
                g.drawString(AxisPara.elementAt(i), 25+xLength, height-30-yLength+i*10);
            }
        }
        g.setColor(Color.black);
//X轴分划
        double axist;
        int axisl,flag;
        long time;

        if(counti < 10){
            time = (GraphPoints.elementAt(0).elementAt(counti-1).getTime().getTime()-GraphPoints.elementAt(0).elementAt(0).getTime().getTime()) / (1000*(counti-1));
            str="Sec";
            double Time = time;

            if(Time >= 60)
            {
                Time /= 60;
                str = "Min";
                if(Time >= 60)
                {
                    Time /= 60;
                    str = "Hour";
                    if(Time >=24)
                    {
                        Time /= 24;
                        str = "Day";
                    }
                }

            }

            axisl = xLength / (counti-1);
            axist = Time;
            flag = counti-1;
        }
        else{
            time = (GraphPoints.elementAt(0).elementAt(counti-1).getTime().getTime()-GraphPoints.elementAt(0).elementAt(0).getTime().getTime()) / 9000;
            str="Sec";
            double Time = time;

            if(Time >= 60)
            {
                Time /= 60;
                str = "Min";
                if(Time >= 60)
                {
                    Time /= 60;
                    str = "Hour";
                    if(Time >=24)
                    {
                        Time /= 24;
                        str = "Day";
                    }
                }
            }

            axisl = xLength/ 9;
            axist = Time;
            flag=9;
        }

        g.setColor(Color.black);
        g.drawString(GraphPoints.elementAt(0).elementAt(0).getTime().toString() ,13 ,height-5);
        g.drawString(str,10+xLength,height-20);

        for(i=1; i< flag;i++){
            g.setColor(Color.black);
            g.drawString("+" + ((int)(axist * i)) ,10 + axisl * i , height-20);
            g.drawLine(10 + axisl * i, height-40, 10 + axisl * i, height-45);
            g.setColor(Color.LIGHT_GRAY);
            g.drawLine(10 + axisl * i, height-45, 10 + axisl * i, height-40-yLength);

        }
        g.drawLine(10 +  xLength, height-40, 10 + xLength, height-40-yLength);
        
        g.setColor(Color.black);
        for(i = 1;i <= 10; i++){
            g.drawString(" " + (double)maxY*(double)i/10,10, height-35-i*yLength/10);
        }


        tempgraph = jg.getImage();
        jg.createJpg(OS);

        return tempgraph;
    };

    /**
     * 求导函数。由DrawGraph函数调用返回特定一组数据的导数
     *
     * @Param DataVec vector型的被求导数组
     *
     * @return tempvec vector型的求导完成后的函数点阵列
     */
    private Vector<Point> derivative(Vector<Point> DataVec){

        int count = DataVec.size();
        Point To; Point From = DataVec.elementAt(0);
        Vector<Point> tempve = new Vector<Point>();
        tempve.addElement(new Point(From.getTime(),0));

        for (int i=1; i< count; i++){
            To=DataVec.elementAt(i);
            long time =(To.getTime()).getTime()-(From.getTime()).getTime();
            time /=1000;

            double Time=time;
            if(time>= 60){
                Time=(double)time/60;

                if(Time >= 60)
                {
                    Time /= 60;
                    if(Time >= 24)
                    {
                        Time /= 24;
                        if(Time >=30)
                            Time /= 30;
                    }
                }
            }


            int value = To.getValue()-From.getValue();
            double der = (double)value/Time;

            tempve.addElement(new Point(To.getTime(),(int)der));

            From = To;
        }

        return tempve;
    };
    /**
     * 求积函数。由DrawGraph函数调用返回特定一组数据的积分
     *
     * @Param DataVec vector型的被积分数组
     *
     * @return tempvec vector型的求导完成后的函数点阵列
     */
    private Vector<Point> integral(Vector<Point> DataVec){
        int count = DataVec.size();
        Point To; Point From = DataVec.elementAt(0);
        Vector<Point> tempve = new Vector<Point>();

        long time =DataVec.elementAt(1).getTime().getTime()-From.getTime().getTime();
        time /=1000;
        double Time=time;
            if(time>= 60){
                Time=(double)time/60;
                if(Time >= 60)
                {
                    Time /= 60;
                    if(Time >= 24)
                    {
                        Time /= 24;
                        if(Time >=30)
                            Time /= 30;
                    }
                }
            }


        tempve.addElement(new Point(From.getTime(),0));
        int integ=0;

        for (int i=1; i< count; i++){
            To=DataVec.elementAt(i);
            int value = To.getValue()+From.getValue();
            integ += value*Time/2;

            tempve.addElement(new Point(To.getTime(),integ));
            From = To;
        }
        return tempve;
    };
    
    public static void main(String argv[]) throws Exception
    {
        Vector<Vector<Point>> vec = new Vector<Vector<Point>>();
        Graph graph = new Graph();
        OutputStream OS = new java.io.FileOutputStream("test.jpg");
        Vector<String> AP = new Vector<String>();
        Vector<Integer> ID = new Vector<Integer>();
        String stri = "ABCDEFGHI";
        long flag;
        Random r1=new Random();

        int ii,jj;

        /*for(ii=0;ii < 15;ii++){
        Vector<Point> vecc = new Vector<Point>();
            for(jj=0;jj < 100;jj++){
                flag=1212000*(jj+1);
                Date d = new Date();
                d.setTime(flag);
                int cheat = ii+r1.nextInt(20);
                vecc.addElement(new Point(d,cheat));
            }
            vec.addElement(vecc);
            AP.addElement(stri);
            ID.addElement(1);
        }*/
           /**     Vector<Point> vecc = new Vector<Point>();
            vec.addElement(vecc);
            AP.addElement(stri);
            ID.addElement(0);
            System.out.println(new Date().getTime());*/
            Vector<Point> vecc = new Vector<Point>();
            vecc.add(new Point(new Date(10000000), 3));
            vecc.add(new Point(new Date(22000000), 5));
            vecc.add(new Point(new Date(39000000), 6));
            vecc.add(new Point(new Date(59000000), 2));
            vec.addElement(vecc);
            AP.addElement(stri);
            ID.addElement(0);
            System.out.println(new Date().getTime());

        graph.drawGragh(vec, 1, OS, AP, ID);

    }
}
